package com.cmc.cloud.cmclink.doc.controller.admin.si;

import cn.hutool.core.bean.BeanUtil;
import com.cmc.cloud.cmclink.doc.api.document.req.si.DraftConfirmDto;
import com.cmc.cloud.cmclink.doc.constants.UrlConstants;
import com.cmc.cloud.cmclink.doc.convert.BlnoBlPrintLogConvert;
import com.cmc.cloud.cmclink.doc.entity.BlnoBlPrintLogDO;
import com.cmc.cloud.cmclink.doc.enums.ResponseContentTypeEnum;
import com.cmc.cloud.cmclink.doc.service.si.BlnoBlPrintLogService;
import com.cmc.cloud.cmclink.doc.service.si.BlnoService;
import com.cmc.cloud.cmclink.doc.util.I18nsUtil;
import com.cmc.cloud.cmclink.doc.vo.blnoblprintlogvo.*;
import com.cmes.framework.biz.advice.annotations.UseResponsePropertyAdvice;
import com.cmes.framework.common.pojo.CommonResult;
import com.cmes.framework.common.pojo.PageResult;
import com.cmes.framework.operatelog.core.annotations.OperateLog;
import com.cmes.framework.operatelog.core.enums.OperateTypeEnum;
import com.cmes.framework.security.core.util.SecurityFrameworkUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

import static com.cmc.cloud.cmclink.doc.constants.errorconstant.BlnoErrorCodeConstants.BLNO_ENTITY_NOT_CHANGE;
import static com.cmc.cloud.cmclink.doc.constants.errorconstant.BlnoErrorCodeConstants.BLNO_FLUSH_ENTITY_TIP;
import static com.cmc.cloud.cmclink.doc.util.ZipCompressor.ZIP;


/**
 * 提单打印前端接口Controller
 * 
 * @author codegen
 */
@Tag(name = "管理后台 - 提单打印")
@RestController
@Validated
@RequestMapping(UrlConstants.APPLICATION_URL + "/blno-bl-print-log")
public class BlnoBlPrintLogController {

    @Resource
    private BlnoBlPrintLogService blnoBlPrintLogService;

    @Resource
    private BlnoService blnoService;

    @Resource
    private I18nsUtil i18nsUtil;

    @Operation(summary = "创建提单打印-无用")
    @OperateLog(type = OperateTypeEnum.CREATE)
	@PostMapping("/create")
    public CommonResult<Void> createBlnoBlPrintLog(@Valid @RequestBody BlnoBlPrintLogCreateReqVO createReqVO) {
        blnoBlPrintLogService.createBlnoBlPrintLog(createReqVO);
        return CommonResult.success();
    }

    @Operation(summary = "更新提单打印-预览编辑")
    @OperateLog(type = OperateTypeEnum.UPDATE)
	@PostMapping("/update")
    public CommonResult<Void> updateBlnoBlPrintLog(@Valid @RequestBody BlnoBlPrintLogUpdateReqVO updateReqVO) {
        blnoBlPrintLogService.updateBlnoBlPrintLog(updateReqVO);
        return CommonResult.success();
    }

    @Operation(summary = "删除提单打印-无用")
    @OperateLog(type = OperateTypeEnum.DELETE)
	@PostMapping("/delete/{id}")
    @Parameter(name = "id", description = "编号", required = true)
    public CommonResult<Void> deleteBlnoBlPrintLog(@PathVariable("id") Long id) {
        blnoBlPrintLogService.deleteBlnoBlPrintLog(id);
        return CommonResult.success();
    }

    @Operation(summary = "获得提单打印信息-无用")
    @OperateLog(type = OperateTypeEnum.GET)
	@GetMapping("/get/{id}")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public CommonResult<BlnoBlPrintLogRespVO> getBlnoBlPrintLog(@PathVariable("id") Long id) {
        BlnoBlPrintLogDO blnoBlPrintLog = blnoBlPrintLogService.getBlnoBlPrintLog(id);
        return CommonResult.success(BlnoBlPrintLogConvert.INSTANCE.convert(blnoBlPrintLog));
    }

    @Operation(summary = "根据主提单ID查询提单预览")
    @OperateLog(type = OperateTypeEnum.GET)
    @GetMapping("/getBlnoBlPrintLogPreview/{id}")
    @Parameter(name = "id", description = "提单ID", required = true, example = "1024")
    public CommonResult<BlnoBlPrintLogRespVO> getBlnoBlPrintLogPreview(@PathVariable("id") Long blnoId) {
        BlnoBlPrintLogDO blnoBlPrintLog = blnoBlPrintLogService.getBlnoBlPrintLogPreview(blnoId);
        return CommonResult.success(BlnoBlPrintLogConvert.INSTANCE.convert(blnoBlPrintLog));
    }

    @Operation(summary = "获得提单打印列表-无用")
    @OperateLog(type = OperateTypeEnum.GET)
	@GetMapping("/list")
    @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
    public CommonResult<List<BlnoBlPrintLogRespVO>> getBlnoBlPrintLogList(@RequestParam("ids") Collection<Long> ids) {
        List<BlnoBlPrintLogDO> list = blnoBlPrintLogService.getBlnoBlPrintLogList(ids);
        return CommonResult.success(BlnoBlPrintLogConvert.INSTANCE.convertList(list));
    }

    @Operation(summary = "获得提单打印分页-无用")
    @OperateLog(type = OperateTypeEnum.GET)
	@GetMapping("/page")
    public CommonResult<PageResult<BlnoBlPrintLogRespVO>> getBlnoBlPrintLogPage(@Valid BlnoBlPrintLogPageReqVO pageVO) {
        PageResult<BlnoBlPrintLogDO> pageResult = blnoBlPrintLogService.getBlnoBlPrintLogPage(pageVO);
        List<BlnoBlPrintLogRespVO> results = BlnoBlPrintLogConvert.INSTANCE.convertList(pageResult.getList());
        return CommonResult.success(new PageResult<>(results,pageResult.getTotal()));
    }

    @Operation(summary = "PrintB/L 列表页")
    @OperateLog(type = OperateTypeEnum.GET)
    @PostMapping("/getPrintBL")
    @UseResponsePropertyAdvice
    @PreAuthorize("@ss.hasPermission('doc:printBL:search')")
    public CommonResult<PageResult<PrintBlRespVo>> getPrintBl(@Valid @RequestBody PrintBlReqVo pageVO) {
        PageResult<PrintBlRespVo> pageResult = blnoBlPrintLogService.getPrintBlPage(pageVO);
        return CommonResult.success(pageResult);
    }

    @Operation(summary = "打印编辑")
    @OperateLog(type = OperateTypeEnum.UPDATE)
    @PostMapping("/pdfCreateAnEdit")
    @PreAuthorize("@ss.hasPermission({'doc:printBL:draftoption','doc:printBL:perviewopton','doc:printBL:printoption'})")
    public void pdfCreateAnEdit(@Valid @RequestBody BlnoBlPrintLogCreateReqVO createReqVO,HttpServletResponse response) throws IOException{
        byte[] result = blnoBlPrintLogService.pdfCreateAnEdit(createReqVO);
        if (createReqVO.getFileName().endsWith(ZIP) ){
            response.setContentType(ResponseContentTypeEnum.ZIP.getContentType());
        }else {
            response.setContentType(ResponseContentTypeEnum.PDF.getContentType());
        }

        response.setHeader("Content-Disposition", "attachment; filename=\"" + createReqVO.getFileName() + "\"");
        response.setContentLength(result.length);

        // 写入响应流
        try (ServletOutputStream outputStream = response.getOutputStream()) {
            outputStream.write(result);
            outputStream.flush();
        }
    }

    @Operation(summary = "批量打印")
    @OperateLog(type = OperateTypeEnum.OTHER)
    @PostMapping("/batchPrintBl")
    @PreAuthorize("@ss.hasPermission({'ddoc:printBL:Batchconfirmationpreviewbl','doc:printBL:Batchconfirmationprint','doc:printBL:Draftbach'})")
    public void batchPrintBl(@Valid @RequestBody BlnoPrintBatchOperationReqDto blnoPrintBatchOperationReqDto,HttpServletResponse response) throws IOException{
        File file = blnoBlPrintLogService.batchPrintBl(blnoPrintBatchOperationReqDto);

        if (file.getName().endsWith(ZIP) ){
            response.setContentType(ResponseContentTypeEnum.ZIP.getContentType());
        }else {
            response.setContentType(ResponseContentTypeEnum.PDF.getContentType());
        }
        response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");

        // 写入响应流
        try (ServletOutputStream outputStream = response.getOutputStream();
             FileInputStream fis = new FileInputStream(file)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
        }
    }

    @Operation(summary = "获取提单维护信息")
    @OperateLog(type = OperateTypeEnum.GET)
    @GetMapping("/getBlnoMaintenanceInfo/{blnoId}")
    @PreAuthorize("@ss.hasPermission('doc:printBL:siperview')")
    @Parameter(name = "blnoId", description = "提单ID", required = true, example = "1024")
    public CommonResult<BlnoMaintenanceInfoRespVO> getBlnoMaintenanceInfo(@PathVariable("blnoId") Long blnoId) {
        BlnoMaintenanceInfoRespVO maintenanceInfo = blnoBlPrintLogService.getBlnoMaintenanceInfo(blnoId,null);
        return CommonResult.success(maintenanceInfo);
    }
    @Operation(summary = "draft确认")
    @OperateLog(type = OperateTypeEnum.UPDATE)
    @PreAuthorize("@ss.hasPermission('doc:printBL:draftConfirm')")
    @PostMapping("/draftConfirm")
    public CommonResult<Void> draftConfirm(@Valid @RequestBody DraftConfirmReqDto draftConfirmReqDto) {
        DraftConfirmDto draftConfirmDto = BeanUtil.copyProperties(draftConfirmReqDto, DraftConfirmDto.class);
        draftConfirmDto.setConfirmer(String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        draftConfirmDto.setConfirmDate(LocalDateTime.now());
        blnoService.draftConfirm(draftConfirmDto);
        return CommonResult.success();
    }

    @Operation(summary = "draft批量确认")
    @OperateLog(type = OperateTypeEnum.UPDATE)
    @PreAuthorize("@ss.hasPermission('doc:printBL:BatchconfirmationDraft')")
    @PostMapping("/batchDraftConfirm")
    public CommonResult<Void> batchDraftConfirm(@Valid @RequestBody BlnoPrintBatchOperationReqDto blnoPrintBatchOperationReqDto) {
        blnoService.batchDraftConfirm(blnoPrintBatchOperationReqDto);
        return CommonResult.success();
    }

    @Operation(summary = "批量刷新提单主体")
    @OperateLog(type = OperateTypeEnum.UPDATE)
    @PreAuthorize("@ss.hasPermission('doc:printBL:Batchconfirmationrefreshbl')")
    @PostMapping("/flushBlEntity")
    public CommonResult<Void> flushBlEntity(@Valid @RequestBody BlnoPrintBatchOperationReqDto blnoPrintBatchOperationReqDto) {
        CommonResult<Object> success = CommonResult.success();
        Locale currentLocale = LocaleContextHolder.getLocale();

        List<String> strings = blnoService.flushBlEntity(blnoPrintBatchOperationReqDto);
        if(ObjectUtils.isEmpty(strings)){
            success.setMsg(i18nsUtil.getMessage(BLNO_ENTITY_NOT_CHANGE.getCode(),currentLocale));
        }else {
            String blnos = strings.stream().collect(Collectors.joining(","));
            success.setMsg(blnos+i18nsUtil.getMessage(BLNO_FLUSH_ENTITY_TIP.getCode(),currentLocale));
        }
        return CommonResult.success();
    }


    @Operation(summary = "测试")
    @PostMapping("/printTheDraft/{blnoId}")
    public void printTheDraft(@PathVariable("blnoId") Long blnoId,HttpServletResponse response) {
        blnoBlPrintLogService.printTheDraft(response,blnoId);
    }
}
